// 使用数组实现队列
package main

import (
	"fmt"
)

type ArrayQueue struct {
	data     []interface{} //存放队列数据
	capacity int           //队列容量
	head     int           //对头位置
	tail     int           //队尾位置
}

// 初始化队列
func NewArrayQueue(n int) *ArrayQueue {
	return &ArrayQueue{make([]interface{}, n), n, 0, 0}
}

// 入队
func (this *ArrayQueue) Enqueue(v interface{}) bool {
	if this.tail == this.capacity { //如果队尾的位置和容量相等,说明队列已满
		return false
	}
	this.data[this.tail] = v
	this.tail++
	return true
}

// 出队
func (this *ArrayQueue) Dequeue() interface{} {
	if this.head == this.tail { //如果队头的位置和队尾的位置相等,说明队列已空
		return nil
	}
	v := this.data[this.head]
	this.head++
	return v
}

// 格式化输出
func (this *ArrayQueue) String() string {
	if this.head == this.tail {
		return "empty queue"
	}
	result := ""
	for i := this.head; i <= this.tail-1; i++ {
		result += fmt.Sprintf("%v ", this.data[i])
	}
	return result
}

func main() {
	queue := NewArrayQueue(5)

	//尝试给容量为5的队列入队6个元素,实际也只能入队成功5个元素
	queue.Enqueue(1)
	queue.Enqueue(2)
	queue.Enqueue(3)
	queue.Enqueue(4)
	queue.Enqueue(5)
	queue.Enqueue(6)
	fmt.Println(queue) //1 2 3 4 5

	//出队1个元素
	queue.Dequeue()
	fmt.Println(queue) // 2 3 4 5

	//出队3个元素
	queue.Dequeue()
	queue.Dequeue()
	queue.Dequeue()
	fmt.Println(queue) //5

	//再把最后一个元素出队
	queue.Dequeue()
	fmt.Println(queue) //empty queue
}
